package com.yalonga.dc.examples.r2dbc.configuration;

import com.github.jasync.r2dbc.mysql.JasyncConnectionFactory;
import com.github.jasync.sql.db.SSLConfiguration;
import com.github.jasync.sql.db.interceptor.QueryInterceptor;
import com.github.jasync.sql.db.mysql.pool.MySQLConnectionFactory;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.util.CharsetUtil;
import io.r2dbc.spi.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.r2dbc.connection.R2dbcTransactionManager;
import org.springframework.transaction.ReactiveTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.reactive.TransactionalOperator;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.function.Supplier;

/**
 * Created on 2023/10/13.
 * @author yaolong
 * @description R2dbcMysqlConfiguration
 */

@Configuration
@EnableTransactionManagement // 开启事务的支持
public class R2dbcMysqlConfiguration {


    @Autowired
    SqlLoggingInterceptorSupplier sqlLoggingInterceptorSupplier;
    @Bean
    public ConnectionFactory connectionFactory(R2dbcProperties properties) throws URISyntaxException {
        // 从 R2dbcProperties 中，解析出 host、port、database
        URI uri = new URI(properties.getUrl());
        String host = uri.getHost();
        int port = uri.getPort();
        String database = uri.getPath().substring(1); // 去掉首位的 / 斜杠

        ArrayList<Supplier<QueryInterceptor>> interceptors = new ArrayList<>();
        interceptors.add(() -> sqlLoggingInterceptorSupplier);
        // 创建 jasync Configuration 配置配置对象
        com.github.jasync.sql.db.Configuration configuration = new com.github.jasync.sql.db.Configuration(
                properties.getUsername(),
                host,
                port,
                properties.getPassword(),
                database,
                new SSLConfiguration(),
                CharsetUtil.UTF_8,
                16777216,
                PooledByteBufAllocator.DEFAULT,
                5000,
                null,
                null,
                interceptors
        );
        // 创建 JasyncConnectionFactory 对象
        return new JasyncConnectionFactory(new MySQLConnectionFactory(configuration));
    }

    @Bean
    public ReactiveTransactionManager transactionManager(R2dbcProperties properties) throws URISyntaxException {
        return new R2dbcTransactionManager(this.connectionFactory(properties));
    }

    @Bean
    public TransactionalOperator transactionalOperator(ReactiveTransactionManager reactiveTransactionManager){
        return TransactionalOperator.create(reactiveTransactionManager);
    }
}